import React, { Component } from 'react'
import { CloseCircleFilled, EyeFilled, EyeInvisibleFilled } from '@ant-design/icons'
import { Spin } from 'antd'

/**
 * @author liu_jshan
 * @version 1.4
 * @props {
 *  prefixName: 前缀，对象 {
 *    content: 前缀内容, string or 图标组件
 *    style: 前缀样式
 *  }
 *  passwordInput：是否是密码框， boolean
 *  rules：校验，array
 *    rules：[
 *      {
 *        validate: 校验的方法，需要返回布尔类型，function 参数为value
 *        failMessage: 校验不通过的提示信息，string
 *        successMessage: 校验通过的提示信息，string 非必须
 *      }
 *    ]
 *  style：css样式，对象
 *  placeholder：说明文本，string,
 *  value: 初始值，string
 *  hiddenClearButton: 隐藏清除按钮，boolean
 *  hiddenEyeButton：隐藏密码框眼睛按钮，boolean
 *  suffixName：自定义后缀，string or 组件，是在现有后缀的基础上增加，不是替换
 *  disabled: 是否禁用，boolean,
 *  readOnly: 只读，boolean,
 *  onChange: 值变化的回调方法，function onChange(value)
 * }
 */
class InputWidget extends Component {

  constructor(props) {
    super(props)
    this.state = {
      value: '', //当前的值
      lastValue: '', //原来的值
      validateMessage: '',//校验信息字符串
      validateMessageArr: [],//校验信息数组
      validateSuccess: true, //校验是否通过
      prefixDisplay: false, //前缀显隐
      suffixDisplay: true, //后缀显隐
      eyeDisplay: false, //按钮眼睛显隐
      lookPassword: false, //是否查看密码
      type: 'text',
      loading: true
    }
  }

  async componentDidMount() {
    let prefixDisplay = this.props.prefixName ? true : false //前缀显隐
    let type = this.props.passwordInput === true ? 'password' : 'text'
    let value = this.props.value ? this.props.value : ''
    let eyeDisplay = this.props.passwordInput === true && this.props.hiddenEyeButton !== true ? true : false //密码框眼睛显隐
    let suffixDisplay = this.props.readOnly !== true && this.props.disabled !== true && (this.props.eyeDisplay === true || this.props.suffixName || this.props.hiddenclearButton !== true) ? true : false

    await new Promise((resolve) => {
      this.setState({
        prefixDisplay,
        suffixDisplay,
        type,
        eyeDisplay,
        value,
        loading: false
      }, resolve)
    })
  }

  /**
   * 组件值变化时调用
   * @param {*} value 变化后的值
   * @param {*} callPropsChange 是否调用props的onChange回调函数，默认true
   */
  onChange = async (value, callPropsChange = true) => {
    //先赋值再校验
    let lastValue = this.state.value
    await new Promise(resolve => {
      this.setState({
        lastValue,
        value
      }, resolve)
    })

    await this.validateRules()

    if (callPropsChange && this.props.onChange && typeof this.props.onChange === 'function') {
      await this.props.onChange(value)
    }

    // if (this.state.type === 'password') { //密码框把调试模式的value删掉
    //   this.inputRef.attributes.removeNamedItem('value')
    // }
  }

  validateRules = async () => {
    const value = this.state.value
    let validateMessageArr = []
    let validateMessage = ''
    let validateSuccess = true
    const { rules } = this.props
    if (rules && Array.isArray(rules) && rules.length > 0) {
      for (let i = 0; i < rules.length; i++) {
        const { validate, failMessage, successMessage } = rules[i]
        if (validate && typeof validate === 'function') {
          let res = await validate(value)
          if (res === false) {
            if (validateSuccess === true && validateMessageArr.length > 0) { //之前校验的都是正确的
              validateMessageArr = []
            }
            validateMessageArr.push(failMessage ? failMessage : '请配置校验提示信息！')
            validateSuccess = false
          } else if (res === true && validateSuccess === true && successMessage) {
            validateMessageArr.push(successMessage)
          }
        }
      }
      validateMessage = validateMessageArr.join('; ')
    }

    await new Promise(resolve => {
      this.setState({
        validateMessage,
        validateMessageArr,
        validateSuccess
      }, resolve)
    })

    return validateSuccess
  }

  render() {
    if (this.state.loading === true) return <Spin />
    return (
      <div
        className='inputWidget-mainDiv'
        style={this.props.style ? this.props.style : null}
      >
        <div
          className='inputWidget-inputDiv'
          style={this.state.validateSuccess === false ? { border: '1px solid var(--border-color-seven)' } : null}
        >
          {
            this.state.prefixDisplay === false ? '' :
              <div className='inputWidget-prefix' style={this.props.prefixName.style}>
                {this.props.prefixName.content}
              </div>
          }
          <input
            className={!this.props.readOnly && this.props.disabled === true ? 'inputWidget-input widget-disabled' : 'inputWidget-input'}
            onChange={event => this.onChange(event.target.value)}
            value={this.state.value}
            type={this.state.type}
            placeholder={this.props.placeholder}
            disabled={this.props.disabled}
            readOnly={this.props.readOnly}
            ref={ref => { this.inputRef = ref }}
          >
          </input>
          {
            this.state.suffixDisplay === false ? '' :
              <div className='inputWidget-suffix'>
                {
                  this.state.eyeDisplay === true ?
                    this.state.lookPassword === true ?
                      <EyeFilled
                        onClick={async () => {
                          await new Promise(resolve => {
                            this.setState({
                              lookPassword: false,
                              type: 'password'
                            }, resolve)
                          })
                        }}
                        style={{ paddingRight: '0.5em' }}
                      ></EyeFilled> :
                      <EyeInvisibleFilled
                        onClick={async () => {
                          await new Promise(resolve => {
                            this.setState({
                              lookPassword: true,
                              type: 'text'
                            }, resolve)
                          })
                        }}
                        style={{ paddingRight: '0.5em' }}
                      ></EyeInvisibleFilled> : ''
                }
                {
                  this.props.hiddenClearButton === true ? '' :
                    <CloseCircleFilled
                      onClick={async () => {
                        await new Promise(resolve => {
                          this.setState({
                            lastValue: '',
                            value: '',
                            validateMessage: '',
                            validateMessageArr: [],
                            validateSuccess: true
                          }, resolve)
                        })
                        await this.validateRules()
                        if (this.props.onChange && typeof this.props.onChange === 'function') {
                          await this.props.onChange()
                        }
                      }}
                    ></CloseCircleFilled>
                }
                {this.props.suffixName ? this.props.suffixName : ''}
              </div>
          }
        </div>
        <div className='inputWidget-messageDiv'
          style={{ color: this.state.validateSuccess === true ? 'var(--ordinary-font-color)' : 'var(--danger-font-color)' }}
        >
          {this.state.validateMessage}
        </div>
      </div>
    )
  }
}

export default InputWidget
